package multi_thread.advanced;

import sun.misc.Unsafe;

/**
 * @author Cheng Jun
 * Description: 练习 Unsafe 操作 static 修饰的类变量
 * @version 1.0
 * @date 2021/9/28 21:00
 */
public class UnsafeStaticExample {

    // 练习 Unsafe 操作内存中 的类变量
    // 为什么 theUnsafe.getChar(UnsafeStaticExample.class, nameOffset) 会乱码
    // theUnsafe.getChar(UnsafeStaticExample.class, nameOffset)===> NAME = 첧
    private static String NAME = "cauchy6317";

    private static int age = 18;

    // true 男，false 女
    private volatile boolean isBoy = true;

    public static void main(String[] args) throws Exception {
        UnsafeStaticExample unsafeStaticExample = new UnsafeStaticExample();
        // 获取 Unsafe对象
        Unsafe theUnsafe = UnsafeUtil.theUnsafe();
        long nameOffset = theUnsafe.staticFieldOffset(UnsafeStaticExample.class.getDeclaredField("NAME"));
        System.out.println("theUnsafe.staticFieldOffset ===>nameOffset: " + nameOffset);
        System.out.println("theUnsafe.getChar(UnsafeStaticExample.class, nameOffset)===> NAME = " + theUnsafe.getChar(UnsafeStaticExample.class, nameOffset));

        // 练习 static age
        long ageOffset = theUnsafe.staticFieldOffset(UnsafeStaticExample.class.getDeclaredField("age"));
        System.out.println("theUnsafe.getInt(UnsafeStaticExample.class, ageOffset) ===> age = " + theUnsafe.getInt(UnsafeStaticExample.class, ageOffset));

        theUnsafe.putInt(UnsafeStaticExample.class, ageOffset, 19);
        System.out.println("theUnsafe.putInt(UnsafeStaticExample.class, ageOffset, 19) ===> " + UnsafeStaticExample.age);
        System.out.println("theUnsafe.getAndSetInt(UnsafeStaticExample.class, ageOffset, 20) ===> before getAndSetInt: " +
                theUnsafe.getAndSetInt(UnsafeStaticExample.class, ageOffset, 20));
        System.out.println("theUnsafe.getAndSetInt(UnsafeStaticExample.class, ageOffset, 20) ===> after getAndSetInt: " +
                UnsafeStaticExample.age);
        // 练习操作 volatile 修饰的实例变量
        long isBoyOffset = theUnsafe.objectFieldOffset(unsafeStaticExample.getClass().getDeclaredField("isBoy"));
        System.out.println("theUnsafe.getObjectVolatile ===> isBoy = " + theUnsafe.getBooleanVolatile(unsafeStaticExample, isBoyOffset));
        theUnsafe.putBooleanVolatile(unsafeStaticExample, isBoyOffset, false);
        System.out.println("theUnsafe.putBooleanVolatile ===> isBoy = " + unsafeStaticExample.isBoy);

    }
}


